package net.wanglu.www.zzz.rule.artcl;

import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.np._NPTuple;
import edu.stanford.nlp.ling.TaggedWord;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.tregex.TregexMatcher;
import edu.stanford.nlp.trees.tregex.TregexPattern;

public class BodyParts extends _ArticleRule {

	public final Pattern BodyParts = Pattern.compile("\\bhead\\b|\\bbrain\\b|\\bskull\\b|\\bhair\\b|\\bforehead\\b|\\btemple\\b|\\beyebrow\\b|\\beyelash\\b|\\bophryon\\b|\\beye\\b|\\bear\\b|\\bnose\\b|\\bcheek\\b|\\bdimple\\b|\\bmole\\b|\\bphiltrum\\b|\\blip\\b|\\bmouth\\b|\\bcavity\\b|\\btooth\\b|\\buvual\\b|\\btonsil\\b|\\btongue\\b|\\bvocal cords\\b|\\bdecayed tooth\\b|\\bgum\\b|\\bpalate\\b|\\bincisors\\b|\\bcanine tooth\\b|\\bpremolars\\b|\\bmolars\\b|\\bdenlture\\b|\\bchin\\b|\\bmustache\\b|\\bbeard\\b|\\bwhiskers\\b|\\bsidebums\\b|\\bAdams apple\\b|\\bthroat\\b|\\bneck\\b|\\bcervical vertebra\\b|\\belbow joint\\b|\\bhand\\b|\\barm\\b|\\bpalm\\b|\\bfinger\\b|\\bnail\\b|\\bthumb\\b|\\bforefinger\\b|\\bmiddle finger\\b|\\bthird finger\\b|\\blittle finger\\b|\\bball\\b|\\bhalf moon\\b|\\bfist\\b|\\bknuckle\\b|\\bback\\b|\\bwrist\\b|\\belbow\\b|\\bcollarbone\\b|\\bshoulder\\b|\\bshoulder blade\\b|\\bshoulder joint\\b|\\bpit\\b|\\bbreastbone\\b|\\bjoint\\b|\\brib\\b|\\bchest\\b|\\bnipple\\b|\\barmpit\\b|\\barmpit hair\\b|\\babdomen\\b|\\bnavel\\b|\\bwaist\\b|\\blumbar vertebrae\\b|\\bback\\b|\\bbackbone\\b|\\bblood vessel\\b|\\bvein\\b|\\bartery\\b|\\bcapillary\\b|\\bnerve\\b|\\bwindpipe\\b|\\bspinal marrow\\b|\\binternal organs\\b|\\bheart\\b|\\bdiaphragm\\b|\\blung\\b|\\bkidney\\b|\\bstomach\\b|\\bgullet\\b|\\bliver\\b|\\bgall bladder\\b|\\bpancreas\\b|\\bspleen\\b|\\bduodenum\\b|\\bsmall intestine\\b|\\blarge intestine\\b|\\bblind gut\\b|\\bvermiform appendix\\b|\\brectum\\b|\\banus\\b|\\bhip\\b|\\bbuttock\\b|\\bpelvis\\b|\\bprivate parts\\b|\\bbladder\\b|\\bpenis\\b|\\btesticles\\b|\\bscroticles\\b|\\burine\\b|\\bovary\\b|\\bwomb\\b|\\bvagina\\b|\\bbone\\b|\\bskeleton\\b|\\bthigh\\b|\\bkneecap\\b|\\bsinew\\b|\\bmuscle\\b|\\bknee\\b|\\bleg\\b|\\bshank\\b|\\bcalf\\b|\\bfoot\\b|\\binstep\\b|\\btoes\\b|\\bankle\\b|\\bAchilless tendon\\b|\\bheel\\b|\\bsole\\b|\\barch\\b");
	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		_NPTuple npt = (_NPTuple) objects[1];
		Tree NP = npt.getNP();
		if ( NP.depth() != 2) return Rule.Inapplicable;//如果不是叶子节点的父母则不符合要求
		TaggedWord headword = npt.getHeadword();
		if ( "NN".equals(headword.tag())) {
			return Rule.Applicable;//如果中心词是名词则符合要求，否则不符合
		} else {
			return Rule.Inapplicable;
		}
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if ( this.applicable(objects) == Rule.Inapplicable) return Rule.Inapplicable;
		
		_NPTuple npt = (_NPTuple) objects[1];
		Tree NP = npt.getNP();

		/*
		 * 名词短语中的headword
		 */
		TaggedWord headword = npt.getHeadword();
		if ( !this.BodyParts.matcher(headword.word()).find()) return Rule.Inapplicable;
		
		TregexPattern pattern = null;
		TregexMatcher matcher = null;

		/*
		 * 名词短语中含有的冠词，也可能没有
		 */
		Tree dt = null;
		sb.clear();
		sb.append("/\\bDT\\b/");
		pattern = TregexPattern.compile(sb.toString());
		matcher = pattern.matcher(NP);
		if ( matcher.find()) {
			dt = matcher.getMatch();
		}

		if ( dt == null) {
			BadEgg egg = new BadEgg();
			egg.whereIsWrong = NP;
			egg.setProperty(BadEgg.Error);
			egg.setViolatedRule(this);
			return egg;									
		} else {
			String dtWord = dt.taggedYield().get(0).word();
			if( "the".equalsIgnoreCase(dtWord)) {
				return null;
			} else if ( "a".equalsIgnoreCase(dtWord) || "an".equalsIgnoreCase(dtWord)) {
				BadEgg egg = new BadEgg();
				egg.whereIsWrong = NP;
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				return egg;					
			} else {
				return Rule.Inapplicable;
			}
		}
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		sb.append("<p>");
		sb.append("在某些词组中表示身体部位的名词前常加the。");
		sb.append("</p>");			
		return sb.toString();
	}
}
